/**
 * 
 */
package com.nextive.interview.service.impl;

import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;

import com.nextive.interview.dto.UserPreferences;
import com.nextive.interview.service.UserInfoService;
import com.nextive.interview.util.ValidationUtil;

/**
 * Implementation class of <code>UserInfoService</code>. It is in charge of implementing 
 * all services related to user preferences. This is done via <code>SharedPreferences</code>. 
 * @author Cesar Roman
 *
 */
public class UserInfoServiceImpl implements UserInfoService {

	/**
	 * Application's context.
	 */
	private Context context;
	
	/**
	 * Default constructor.
	 * @param context
	 */
	public UserInfoServiceImpl(Context context) {
		
		this.context = context;
		
	}
	
	/**
	 * It determines if it is user's first access. This is done via querying any 
	 * data in <code>ShaerdPreferences</code>.
	 * @return true if it is first access
	 */
	@Override
	public boolean isUserFirstAccess() {
		
		SharedPreferences sharedPreferences = obtainSharedPreferences();
		return !sharedPreferences.contains(UserInfoKey.NAME.name());
		
	}

	/**
	 * It either saves or updates user preferences.
	 * @param preferences
	 * @return true if updated successfully
	 */
	@Override
	public boolean saveOrUpdateUserInfo(UserPreferences preferences) {
		
		// none of the fields may be null/empty
		if (!ValidationUtil.isValidStringInput(preferences.getName()) || 
				!ValidationUtil.isValidEmailInput(preferences.getEmail()) || 
				!ValidationUtil.isValidStringInput(preferences.getRecipientEmail()) || 
				preferences.getMetricOption() == null)
			return false;
		
		SharedPreferences sharedPreferences = obtainSharedPreferences();
		Editor editor = sharedPreferences.edit();
		
		editor.putString(UserInfoKey.NAME.name(), preferences.getName());
		editor.putString(UserInfoKey.EMAIL.name(), preferences.getEmail());
		editor.putString(UserInfoKey.RECIPIENT.name(), preferences.getRecipientEmail());
		editor.putString(UserInfoKey.WEIGHT_METRIC.name(), preferences.getMetricOption().name());
		
		editor.commit();
		
		return true;
		
	}
	
	/**
	 * It fetches user preferences.
	 * @return
	 */
	@Override
	public UserPreferences fetchUserInfo() {
		
		SharedPreferences sharedPreferences = obtainSharedPreferences();
		
		return new UserPreferences(
				sharedPreferences.getString(UserInfoKey.NAME.name(), null),
				sharedPreferences.getString(UserInfoKey.EMAIL.name(), null),
				sharedPreferences.getString(UserInfoKey.RECIPIENT.name(), null),
				buildMetric(sharedPreferences.getString(UserInfoKey.WEIGHT_METRIC.name(), 
						UserInfoService.DEFAULT_METRIC.name())));
		
	}
	
	/**
	 * It builds a <code>UserInfoService.Metrics</code> given a value.
	 * @param value
	 * @return
	 */
	private static Metric buildMetric(String value) {
		
		try {
		
			return Metric.valueOf(value);
			
		} catch(Exception e) {
			return UserInfoService.DEFAULT_METRIC;
		}
		
	}

	/**
	 * It obtains shared preferences to be queried later on.
	 * @return
	 */
	private SharedPreferences obtainSharedPreferences() {
		
		return context.getSharedPreferences(UserInfoKey.USER_INFO_PREFERENCES.name(), Context.MODE_PRIVATE);
		
	}

}